﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GiaoTrinhEPU.Repositories.Interfaces;
using GiaoTrinhEPU.Caching;
using GiaoTrinhEPU.Repositories.DataModels;

namespace GiaoTrinhEPU.Repositories.Repositories
{
    public class SyllabusRepository : BaseRepository, ISyllabusRepository
    {
        public SyllabusRepository() : base() { }
        public SyllabusRepository(ICacheProvider cacheProvider) : base(cacheProvider) { }

        /// <summary>
        /// Clear cache of all banks
        /// </summary>
        public void ClearCache()
        {
            Cache.Invalidate("syllabus");
        }

        /// <summary>
        /// Clear cache of the syllabus
        /// </summary>
        /// <param name="key"></param>
        public void ClearCache(String key)
        {
            Cache.Invalidate("syllabus-" + key);
        }
        /// <summary>
        /// Create a new bank
        /// </summary>
        /// <param name="item"></param>
        public void CreateSyllabus(Syllabus item)
        {
            try
            {
                using (var db = new ThuVienEPUDataContext())
                {
                    db.Syllabus.InsertOnSubmit(item);
                    db.SubmitChanges();
                }
            }
            catch (Exception ex)
            {
                Logger.Writer.Write(ex.Message, ex.Source);
            }
        }

        // <summary>
        /// Update Syllabus
        /// </summary>
        /// <param name="item"></param>
        public void UpdateSyllabus(Syllabus item)
        {
            try
            {
                using (var db = new ThuVienEPUDataContext())
                {
                    var syllabus = db.Syllabus.Single(a => a.Id.Equals(item.Id));
                    syllabus.Id = (int)item.Id;
                    syllabus.Name = item.Name;
                    syllabus.Code = item.Code;
                    syllabus.PublisherId = item.PublisherId;
                    syllabus.DegreeId = item.DegreeId;
                    syllabus.LevelId = item.LevelId;
                    syllabus.PublisherId = item.PublisherId;
                    syllabus.NPage = (int)item.NPage;
                    syllabus.NChapter = (int)item.NChapter;
                    syllabus.Price = item.Price;
                    syllabus.CreatedBy = item.CreatedBy;
                    syllabus.CreatedDate = item.CreatedDate;
                    syllabus.ModifiedCount = item.ModifiedCount;
                    syllabus.ModifiedDate = item.ModifiedDate;
                    syllabus.ModifiedBy = item.ModifiedBy;
                    syllabus.Description = item.Description;
                    db.SubmitChanges();
                }
            }
            catch (Exception ex)
            {
                Logger.Writer.Write(ex.Message, ex.Source);
            }
        }
        /// <summary>
        /// Delete a Syllabus
        /// </summary>
        /// <param name="id"></param>
        public void DeleteSyllabus(int id)
        {
            try
            {
                using (var db = new ThuVienEPUDataContext())
                {
                    var syllabus = db.Syllabus.Single(a => a.Id.Equals(id));
                    db.Syllabus.DeleteOnSubmit(syllabus);
                    db.SubmitChanges();
                }
            }
            catch (Exception ex)
            {
                Logger.Writer.Write(ex.Message, ex.Source);
            }
        }
        /// <summary>
        /// List all Syllabus in database, order by Syllabus's name
        /// </summary>
        /// <returns></returns>
        public IEnumerable<SyllabusModel> ListSyllabus(bool cacheEnabled = true)
        {
            if (cacheEnabled == true)
            {
                // if it's not in the cache, we need to read it form the repository// First, check the cache
                IEnumerable<SyllabusModel> syllabusData = Cache.Get("syllabus") as IEnumerable<SyllabusModel>;

                // if it's not in the cache, we need to read it form the repository
                if (syllabusData == null)
                {
                    //Get the repository data
                    try
                    {
                        using (var db = new ThuVienEPUDataContext())
                        {
                            syllabusData = (from x in db.Syllabus
                                          join y in db.Departments
                                          on x.DepartmentId equals y.Id
                                          join z in db.Publishers
                                          on x.PublisherId equals z.Id
                                          join t in db.Degrees
                                          on x.DegreeId equals t.Id
                                          join r in db.Levels
                                          on x.LevelId equals r.Id
                                            select new SyllabusModel
                                          {
                                              Id = x.Id,
                                              Name = x.Name,
                                              Code=x.Code,
                                              NChapter =(int)x.NChapter,
                                              NPage = (int)x.NPage,
                                              Price=(int)x.Price,
                                              Description = x.Description,
                                              DepartmentName = y.Name,
                                              PublisherName = z.Name,
                                              DegreeName= t.Name,
                                              LevelName = r.Name,
                                              ModifiedBy=x.ModifiedBy,
                                              ModifiedCount =x.ModifiedCount,
                                              ModifiedDate = x.ModifiedDate,
                                              CreatedBy = x.CreatedBy,
                                              CreatedDate = x.CreatedDate,
                                          }).OrderBy(a => a.Name).ToList();
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Writer.Write(ex.Message, ex.Source);
                    }

                    if (syllabusData.Any())
                    {
                        Cache.Set("syllabus", syllabusData, GiaoTrinhEPU.Caching.Properties.Settings.Default.CacheTime);
                    }
                }
                return syllabusData;
            }
            else
            {
                //Get the repository data
                IEnumerable<SyllabusModel> syllabusData = null;

                try
                {
                    using (var db = new ThuVienEPUDataContext())
                    {
                        syllabusData = (from x in db.Syllabus
                                        join y in db.Departments
                                        on x.DepartmentId equals y.Id
                                        join z in db.Publishers
                                        on x.PublisherId equals z.Id
                                        join t in db.Degrees
                                        on x.DegreeId equals t.Id
                                        join r in db.Levels
                                        on x.LevelId equals r.Id
                                        select new SyllabusModel
                                        {
                                            Id = x.Id,
                                            Name = x.Name,
                                            Code = x.Code,
                                            NChapter = (int)x.NChapter,
                                            NPage = (int)x.NPage,
                                            Price=(int)x.Price,
                                            Description = x.Description,
                                            DepartmentName = y.Name,
                                            PublisherName = z.Name,
                                            DegreeName = t.Name,
                                            LevelName = r.Name,
                                            ModifiedBy = x.ModifiedBy,
                                            ModifiedCount = x.ModifiedCount,
                                            ModifiedDate = x.ModifiedDate,
                                            CreatedBy = x.CreatedBy,
                                            CreatedDate = x.CreatedDate,
                                        }).OrderBy(a => a.Name).ToList();
                    }
                }
                catch (Exception ex)
                {
                    Logger.Writer.Write(ex.Message, ex.Source);
                }

                return syllabusData;
            }
        }
        /// <summary>
        /// Get a Syllabus if we know it's id
        /// </summary>
        /// <param name="id">id of the banner</param>
        /// <returns>
        /// return a banner
        /// </returns>
        public Syllabus GetSyllabusById(int id)
        {
            Cache.Invalidate("syllabus-" + id);
            Syllabus syllabusData = Cache.Get("syllabus-" + id) as Syllabus;
            if (syllabusData == null)
            {
                try
                {
                    using (var db = new ThuVienEPUDataContext())
                    {
                        syllabusData = db.Syllabus.Single(a => a.Id.Equals(id));
                    }
                }
                catch (Exception ex)
                {
                    Logger.Writer.Write(ex.Message, ex.Source);
                }

                if (syllabusData != null)
                {
                    Cache.Set("syllabus-" + id, syllabusData, GiaoTrinhEPU.Caching.Properties.Settings.Default.CacheTime);
                }
            }
            return syllabusData;
        }
        /// <summary>
        /// check name of the syllabus already exist in database 
        /// </summary>
        /// <param name="name"></param>
        /// <returns>
        /// return true if exist, else false
        /// </returns>
        public bool HasNameExisted(string name)
        {
            bool isExisted = false;
            try
            {
                using (var db = new ThuVienEPUDataContext())
                {
                    var list = (from a in db.Syllabus
                                where a.Name.Equals(name)
                                select a.Id).ToList();
                    isExisted = list.Count > 0;
                }
            }
            catch (Exception ex)
            {
                Logger.Writer.Write(ex.Message, ex.Source);
            }
            return isExisted;
        }

        /// <summary>
        /// check duplication of the banner in case of updating the banner
        /// </summary>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool HasNameDuplicated(int id, string name)
        {
            bool isDuplicated = false;
            try
            {
                using (var db = new ThuVienEPUDataContext())
                {
                    var list = (from a in db.Syllabus
                                where a.Name.Equals(name)
                                where !a.Id.Equals(id)
                                select a.Id).ToList();
                    isDuplicated = list.Count > 0;
                }
            }
            catch (Exception ex)
            {

                Logger.Writer.Write(ex.Message, ex.Source);
            }
            return isDuplicated;
        }

    }
}
